package com.qy.changemachine.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.LinkAddress;
import android.util.Log;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.List;

public class EthernetConfigurator {

    private static final String TAG = "EthernetConfigurator";
    private Object ethernetManager;

    public EthernetConfigurator(Context context) {
        try {
            // 获取 EthernetManager 实例
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");
            Method getSystemServiceMethod = Context.class.getMethod("getSystemService", String.class);
            ethernetManager = getSystemServiceMethod.invoke(context, "ethernet");
            Log.d(TAG, "EthernetManager instance obtained: " + ethernetManager);
        } catch (Exception e) {
            Log.e(TAG, "Failed to get EthernetManager", e);
            throw new IllegalStateException("Failed to get EthernetManager", e);
        }
    }

    /**
     * 更新完整的网络配置（IP 地址、网关、DNS 和子网掩码）
     */
    public void configureEthernet(String interfaceName, String ipAddress, String gateway, String dns, String subnetMask) {
        if (ethernetManager == null) {
            throw new IllegalStateException("EthernetManager is not available");
        }

        try {
            // 创建 StaticIpConfiguration 对象
            Class<?> staticIpConfigClass = Class.forName("android.net.StaticIpConfiguration");
            Constructor<?> staticIpConfigConstructor = staticIpConfigClass.getConstructor();
            Object staticIpConfig = staticIpConfigConstructor.newInstance();

            // 设置 IP 地址和子网掩码
            InetAddress inetAddr = InetAddress.getByName(ipAddress);
            int prefixLength = getPrefixLengthFromMask(subnetMask);
            Constructor<?> linkAddressConstructor = LinkAddress.class.getConstructor(InetAddress.class, int.class);
            Object linkAddress = linkAddressConstructor.newInstance(inetAddr, prefixLength);

            // 直接设置 StaticIpConfiguration 的 ipAddress 字段
            @SuppressLint("SoonBlockedPrivateApi") Field ipAddressField = staticIpConfigClass.getDeclaredField("ipAddress");
            ipAddressField.setAccessible(true);
            ipAddressField.set(staticIpConfig, linkAddress);

            // 设置网关
            InetAddress gatewayAddr = InetAddress.getByName(gateway);
            @SuppressLint("SoonBlockedPrivateApi") Field gatewayField = staticIpConfigClass.getDeclaredField("gateway");
            gatewayField.setAccessible(true);
            gatewayField.set(staticIpConfig, gatewayAddr);

            // 设置 DNS
            InetAddress dnsAddr = InetAddress.getByName(dns);
            @SuppressLint("SoonBlockedPrivateApi") Field dnsServersField = staticIpConfigClass.getDeclaredField("dnsServers");
            dnsServersField.setAccessible(true);
            List<InetAddress> dnsServers = (List<InetAddress>) dnsServersField.get(staticIpConfig);
            dnsServers.add(dnsAddr);

            // 创建 IpConfiguration 对象
            Class<?> ipConfigClass = Class.forName("android.net.IpConfiguration");
            Constructor<?> ipConfigConstructor = ipConfigClass.getConstructor();
            Object ipConfig = ipConfigConstructor.newInstance();

            // 设置 StaticIpConfiguration
            Method setStaticIpConfigurationMethod = ipConfigClass.getMethod("setStaticIpConfiguration", staticIpConfigClass);
            setStaticIpConfigurationMethod.invoke(ipConfig, staticIpConfig);

            // 设置 IP 分配方式为静态
            Class<?> ipAssignmentClass = Class.forName("android.net.IpConfiguration$IpAssignment");
            Method valueOfMethod = ipAssignmentClass.getMethod("valueOf", String.class);
            Object staticAssignment = valueOfMethod.invoke(null, "STATIC");
            Method setIpAssignmentMethod = ipConfigClass.getMethod("setIpAssignment", ipAssignmentClass);
            setIpAssignmentMethod.invoke(ipConfig, staticAssignment);

            // 获取 EthernetManager 的 setConfiguration 方法
            Method setConfigurationMethod = ethernetManager.getClass().getDeclaredMethod("setConfiguration", String.class, ipConfigClass);
            setConfigurationMethod.setAccessible(true);

            // 应用配置
            setConfigurationMethod.invoke(ethernetManager, interfaceName, ipConfig);
            Log.d(TAG, "Ethernet configuration applied successfully");

        } catch (Exception e) {
            Log.e(TAG, "Failed to configure Ethernet", e);
            throw new IllegalStateException("Failed to configure Ethernet", e);
        }
    }

    /**
     * 仅更新网关地址
     */
    public void updateGateway(String interfaceName, String newGateway) {
        if (ethernetManager == null) {
            throw new IllegalStateException("EthernetManager is not available");
        }

        try {
            // 获取当前的网络配置
            Method getConfigurationMethod = ethernetManager.getClass().getDeclaredMethod("getConfiguration", String.class);
            getConfigurationMethod.setAccessible(true);
            Object ipConfig = getConfigurationMethod.invoke(ethernetManager, interfaceName);

            // 获取 StaticIpConfiguration
            Class<?> ipConfigClass = Class.forName("android.net.IpConfiguration");
            Method getStaticIpConfigurationMethod = ipConfigClass.getMethod("getStaticIpConfiguration");
            Object staticIpConfig = getStaticIpConfigurationMethod.invoke(ipConfig);

            if (staticIpConfig == null) {
                throw new IllegalStateException("StaticIpConfiguration is not available");
            }

            // 获取当前的 IP 地址、DNS 和子网掩码
            Class<?> staticIpConfigClass = Class.forName("android.net.StaticIpConfiguration");
            Field ipAddressField = staticIpConfigClass.getDeclaredField("ipAddress");
            ipAddressField.setAccessible(true);
            LinkAddress linkAddress = (LinkAddress) ipAddressField.get(staticIpConfig);

            Field dnsServersField = staticIpConfigClass.getDeclaredField("dnsServers");
            dnsServersField.setAccessible(true);
            List<InetAddress> dnsServers = (List<InetAddress>) dnsServersField.get(staticIpConfig);

            // 设置新的网关
            InetAddress gatewayAddr = InetAddress.getByName(newGateway);
            Field gatewayField = staticIpConfigClass.getDeclaredField("gateway");
            gatewayField.setAccessible(true);
            gatewayField.set(staticIpConfig, gatewayAddr);

            // 创建新的 IpConfiguration 对象
            Constructor<?> ipConfigConstructor = ipConfigClass.getConstructor();
            Object newIpConfig = ipConfigConstructor.newInstance();

            // 设置 StaticIpConfiguration
            Method setStaticIpConfigurationMethod = ipConfigClass.getMethod("setStaticIpConfiguration", staticIpConfigClass);
            setStaticIpConfigurationMethod.invoke(newIpConfig, staticIpConfig);

            // 设置 IP 分配方式为静态
            Class<?> ipAssignmentClass = Class.forName("android.net.IpConfiguration$IpAssignment");
            Method valueOfMethod = ipAssignmentClass.getMethod("valueOf", String.class);
            Object staticAssignment = valueOfMethod.invoke(null, "STATIC");
            Method setIpAssignmentMethod = ipConfigClass.getMethod("setIpAssignment", ipAssignmentClass);
            setIpAssignmentMethod.invoke(newIpConfig, staticAssignment);

            // 获取 EthernetManager 的 setConfiguration 方法
            Method setConfigurationMethod = ethernetManager.getClass().getDeclaredMethod("setConfiguration", String.class, ipConfigClass);
            setConfigurationMethod.setAccessible(true);

            // 应用配置
            setConfigurationMethod.invoke(ethernetManager, interfaceName, newIpConfig);
            Log.d(TAG, "Gateway updated successfully");

        } catch (Exception e) {
            Log.e(TAG, "Failed to update gateway", e);
            throw new IllegalStateException("Failed to update gateway", e);
        }
    }

    /**
     * 计算子网掩码的前缀长度
     */
    private int getPrefixLengthFromMask(String subnetMask) {
        try {
            // 将子网掩码转换为字节数组
            InetAddress inetAddress = InetAddress.getByName(subnetMask);
            byte[] maskBytes = inetAddress.getAddress();

            // 计算前缀长度
            int prefixLength = 0;
            for (byte b : maskBytes) {
                for (int i = 7; i >= 0; i--) {
                    if ((b & (1 << i)) != 0) {
                        prefixLength++;
                    } else {
                        return prefixLength;
                    }
                }
            }
            return prefixLength;
        } catch (Exception e) {
            Log.e(TAG, "Failed to calculate prefix length from subnet mask", e);
            return 24; // 默认子网掩码长度
        }
    }
}